package com.doupi.partner.op.interceptor;

import com.alibaba.fastjson.JSON;
import com.doupi.partner.dal.OperationLogMapper;
import com.doupi.partner.dal.constant.LogTypeEnum;
import com.doupi.partner.dal.model.Administrator;
import com.doupi.partner.dal.model.OperationLog;
import com.doupi.partner.op.util.OpUtils;
import com.doupi.partner.util.SpringContextUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.springframework.transaction.annotation.Transactional;

import java.util.Properties;

/**
 * 模型拦截器
 *
 * @author Super Jens Wang
 * @version 1.0 $id: ModelInterceptor.java 2015年9月20日 下午3:19:55 Wang Le $
 */
@Intercepts(@Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }))
public class LogInterceptor implements Interceptor {

	@Override
	@Transactional
	public Object intercept(Invocation invocation) throws Throwable {
		Object object = invocation.getArgs()[1];
		if (object instanceof OperationLog) {
			return invocation.proceed();
		}
		MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
		SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
		if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType) || SqlCommandType.DELETE.equals(sqlCommandType)) {
			insertOperationLog(invocation.getArgs()[0], object);
		}
		return invocation.proceed();
	}

	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	@Override
	public void setProperties(Properties properties) {

	}

	private void insertOperationLog(Object arg, Object obj) {
		Administrator administrator = OpUtils.getCurrentLoginAdministrator ();
		OperationLog operationLog = new OperationLog();
		MappedStatement mappedStatement = (MappedStatement) arg;
		operationLog.setSqlMapId(mappedStatement.getId());
		operationLog.setSql(mappedStatement.getBoundSql(obj).getSql());
		operationLog.setSqlParameter(JSON.toJSONString(obj));
		operationLog.setCreateAdministratorId(administrator.getId());
		String simpleClassName = obj.getClass().getSimpleName();
		switch (mappedStatement.getSqlCommandType()) {
		case INSERT:
			operationLog.setType(LogTypeEnum.INSERT.getCode());
			operationLog.setMemo("新增" + simpleClassName);
			break;
		case DELETE:
			operationLog.setType(LogTypeEnum.DELETE.getCode());
			operationLog.setMemo("删除" + simpleClassName);
			break;
		case UPDATE:
			operationLog.setType(LogTypeEnum.UPDATE.getCode());
			operationLog.setMemo("修改" + simpleClassName);
			break;
		default:
			break;
		}
		SpringContextUtils.getBeanByClass(OperationLogMapper.class).insert(operationLog);
	}

}
